package com.blog.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.blog.entity.*;
import com.blog.mapper.SysArticleMapper;
import com.blog.redis.RedisUtil;
import com.blog.service.ArticleHistoryService;
import com.blog.service.CategoryService;
import com.blog.service.AssociateService;
import com.blog.service.SysArticleService;
import com.blog.util.DateFormatUtil;

import com.blog.util.dto.AjaxResult;
import com.blog.util.laydto.LayDto;
import com.blog.util.laydto.LayDtoUtil;
import com.blog.util.uuid.UUIDUtils;
import com.blog.util.xmSelect.XmSelectData;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.websocket.server.PathParam;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

import static com.blog.redis.RedisKeys.KEY_ARTICLE_TABLE;

/**
 * @author gxcc
 * @auther gxcc
 * @create 2021/10/1 17:03
 */
@Slf4j
@Controller
@RequestMapping("article")
public class SysArticleController {

    @Resource
    SysArticleService articleService;

    @Resource
    SysArticleMapper articleMapper;

    @Resource
    RedisUtil redisUtil;

    @Resource
    CategoryService categoryService;

    @Resource
    AssociateService associateService;

    @Resource
    ArticleHistoryService historyService;

    @GetMapping("/write")
    public String writeArticle(HttpServletRequest request,Model model){
        String articleNum = request.getParameter("articleNum");
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("article_num",articleNum).eq("issued",2);
        List<SysArticle> list = articleService.list(queryWrapper);
        if (list.size()==1){
            model.addAttribute("articleId",list.get(0).getId());
        }
        return "article/article-write";
    }

    /**
     * 后台获取文章列表表格
     * @return
     */
    @GetMapping("/table")
    @ResponseBody
    public LayDto articleTable(){
        List<Map<String,Object>> articleList = articleService.tableList();
        return LayDtoUtil.returnSuccess(0,"",articleList.size(),articleList);
    }


    /**
     * 获取博客详情通过id
     * @param articleNum 博客num
     * @param model thymeleaf渲染值
     * @return
     */
    @GetMapping("/getArticleDetail/{articleNum}")
    public String getArticleDetail(@PathVariable String articleNum, Model model, HttpSession session){
        List<Map<String, Object>> list = articleService.queryArticleDetailByNum(articleNum);
        if (list.size() != 1){
            log.error("文章异常,文章num:{},time:{}",articleNum,DateFormatUtil.dataToStrLong(new Date()));
        }

        Map<String, Object> sysArticle = list.get(0);
        String issued = sysArticle.get("issued").toString();
        //草稿箱跳转至编辑页面
        if ("2".equals(issued)){
            model.addAttribute("articleId",sysArticle.get("id"));
            return "article/article-write";
        }
        Subject subject = SecurityUtils.getSubject();
        SysUser user = (SysUser)subject.getPrincipal();
        //如果用户已登录，增加用户观看记录
        if (user != null){
            //先看是否之前观看过
            QueryWrapper<ArticleHistory> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("article_num",articleNum)
                    .eq("look_user",user.getId());
            List<ArticleHistory> historyList = historyService.list(queryWrapper1);
            if (historyList.size() == 0){
                ArticleHistory articleHistory = new ArticleHistory();
                articleHistory.setHistoryId(UUIDUtils.getUUId());
                articleHistory.setArticleNum((String) sysArticle.get("articleNum"));
                articleHistory.setLookUser(user.getId());
                articleHistory.setActive(1);
                historyService.save(articleHistory);
            }else {
                ArticleHistory articleHistory = historyList.get(0);
                articleHistory.setLookTime(new Date());
                historyService.updateById(articleHistory);
            }
        }
        model.addAttribute("article",sysArticle);
        return "article/article-detail";
    }

    /**
     * 首页展示20条数据
     * @param
     * @return
     */
    @GetMapping("index/queryAllArticle")
    @ResponseBody
    public AjaxResult getAllArticle(){
        IPage<SysArticle> page = new Page<>(1,20);
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("issued",1);
        List<Map<String, Object>> mapList = articleService.queryAllArticle();
        return AjaxResult.success(mapList);
    }

    /**
     * 首页通过分类查询博客
     * @param category 博客分类
     * @return
     */
    @PostMapping("index/queryArticleByCategory")
    @ResponseBody
    public AjaxResult queryArticleByCategory(@PathParam("category") String category){
        List<Map<String,Object>> articleList = articleService.queryArticleByCategory(category);
        return AjaxResult.success(articleList);
    }

    /**
     * 写博客时获取博客分类下拉框数据
     * @return
     */
    @PostMapping("write/queryAllArticleCategory")
    @ResponseBody
    public AjaxResult queryArticleCategory(){
        QueryWrapper<SysCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("create_time");
        List<SysCategory> list = categoryService.list(queryWrapper);
        List<XmSelectData> xmSelectDataList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            XmSelectData xmSelectData = new XmSelectData();
            xmSelectData.setName(list.get(i).getCategoryName());
            xmSelectData.setValue(list.get(i).getId());
            xmSelectDataList.add(xmSelectData);
        }
        return AjaxResult.success(xmSelectDataList);
    }

    /**
     * 保存文章至草稿箱,目前没有登录也可以写文章，后期需要进行登录后才可以写文章
     * @return
     */
    @PostMapping("write/saveArticleToDraft")
    @ResponseBody
    public AjaxResult saveArticleToDraft(HttpServletRequest request){
        String articleTitle = request.getParameter("articleTitle");
        String articleContent = request.getParameter("articleContent");

        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser)subject.getPrincipal();
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author_id",sysUser.getId());
        queryWrapper.eq("title",articleTitle);
        List<SysArticle> list = articleService.list(queryWrapper);

        redisUtil.del(KEY_ARTICLE_TABLE);
        log.info(" ==>数据源redis  type: del   key: "+KEY_ARTICLE_TABLE);

        SysArticle article = new SysArticle();
        article.setId(UUIDUtils.getUUId());
        article.setAuthorId(sysUser.getId());
        article.setTitle(articleTitle);
        article.setActive(1);
        article.setArticleType(1);
        article.setAllowComment(1);
        article.setReleaseForm(1);
        article.setContent(articleContent);
        article.setIssued(2);
        article.setArticleNum(UUIDUtils.getArticleNum());
        article.setAuthorId(sysUser.getId());
        //草稿箱里的文章编号默认为空
        article.setCategoryName("");

        if (list.size() > 0){
            articleService.updateById(article);
        }else {
            articleService.save(article);
        }
        return AjaxResult.success();
    }


    /**
     * 发布博客（直接发布，不经过草稿箱）
     * @param
     * @return
     */
    @PostMapping("write/releaseArticle")
    @ResponseBody
    public AjaxResult releaseArticle(HttpServletRequest request){
        redisUtil.del(KEY_ARTICLE_TABLE);
        log.info(" ==>数据源redis  type: del   key: "+KEY_ARTICLE_TABLE);

        String articleTitle = request.getParameter("articleTitle");
        String category = request.getParameter("category");
        String articleContent = request.getParameter("articleContent");
        String articleType = request.getParameter("articleType");
        String allowComment = request.getParameter("allowComment");
        String releaseForm = request.getParameter("releaseForm");

        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser)subject.getPrincipal();

        //发布前先查询是否有同作者，同题目的文章
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("author_id",sysUser.getId())
                .eq("title",articleTitle)
                .eq("issued",1);
        List<SysArticle> list = articleService.list(queryWrapper);
        if (list.size()>0){
            return AjaxResult.error("不可重复提交");
        }
        //获取分类id集合
        List<String> categoryList = Arrays.asList(category.split(","));
        List<String> sysCategories = new ArrayList<>();
        for (int i = 0; i < categoryList.size(); i++) {
            SysCategory byId = categoryService.getById(categoryList.get(i));
            sysCategories.add(byId.getCategoryName());
        }
        String ss = String.join(",", sysCategories);
        //目前没有登录也可以写文章，后期需要进行登录后才可以写文章

        SysArticle article = new SysArticle();
        String id = UUIDUtils.getUUId();
        article.setId(id);

        Subject currentSubject = SecurityUtils.getSubject();
        SysUser currentUser = (SysUser)currentSubject.getPrincipal();

        article.setAuthorId(currentUser.getId());
        article.setTitle(articleTitle);
        article.setContent(articleContent);
        article.setCategoryName(ss);
        article.setArticleType(Integer.valueOf(articleType));
        article.setAllowComment(Integer.valueOf(allowComment));
        article.setReleaseForm(Integer.valueOf(releaseForm));
        article.setArticleNum(UUIDUtils.getUUId().substring(0,6));
        //1是直接发布
        article.setIssued(1);
        article.setActive(1);
        articleService.save(article);
        //保存至关系表中
        List<SysAssociate> associateList = new ArrayList<>();
        for (int m = 0; m < categoryList.size(); m++) {
            SysAssociate associate = new SysAssociate();
            associate.setArticleId(id);
            associate.setCategoryId(categoryList.get(m));
            associateList.add(associate);
        }
        boolean save = associateService.saveBatch(associateList);
        if (save){
            return AjaxResult.success();
        }else {
            return AjaxResult.error("保存失败");
        }
    }

    /**
     * 后台条件查询博客
     * @param
     * @return
     */
    @GetMapping("admin/queryArticle")
    @ResponseBody
    public LayDto queryArticle(HttpServletRequest request){
        String articleTitle = request.getParameter("articleTitle");
        String articleCategory = request.getParameter("articleCategory");
        String articleAuthor = request.getParameter("articleAuthor");
        List<Map<String,Object>> articleList =  articleService.queryArticleByCondition(articleTitle,articleAuthor,articleCategory);
        return LayDtoUtil.returnSuccess(0,"",articleList.size(),articleList);
    }

    /**
     * 后台通过id删除博客
     * @param
     * @return
     */
    @PostMapping("admin/deleteById")
    @ResponseBody
    public AjaxResult deleteById(HttpServletRequest request) {
        String categoryId = request.getParameter("articleId");
        articleService.removeById(categoryId);
        QueryWrapper<SysAssociate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("article_id",categoryId);
        boolean b = associateService.remove(queryWrapper);
        if (b){
            return AjaxResult.success();
        }else {
            return AjaxResult.error("删除失败");
        }
    }

    @GetMapping("write/selectDetail")
    public String articleSelectDetail(){
        return "article/public/article-selectDetail";
    }


    @GetMapping("write/saveToDraft")
    public String saveToDraft(){
        return "article/public/article-saveToDraft";
    }

    /**
     * 通过用户id查询所有博客
     * @param
     * @return
     */
    @GetMapping("index/queryAllArticleById")
    @ResponseBody
    public AjaxResult queryAllArticleById(HttpServletRequest request){
        String userId = request.getParameter("userId");
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("issued",1);
        queryWrapper.eq("active",1);
        queryWrapper.eq("author_id",userId);
        List<SysArticle> list = articleService.list(queryWrapper);
        return AjaxResult.success(list);
    }

    /**
     * 个人中心查询博客(年月日等高级查询)
     * @param
     * @return
     */
    @GetMapping("index/queryArticleByCondition")
    @ResponseBody
    public AjaxResult queryArticleByCondition(HttpServletRequest request){
        String userId = request.getParameter("authorId");
        String yearTime = request.getParameter("yearTime");
        String monthTime = request.getParameter("monthTime");
        String category = request.getParameter("category");
        String articleTitle = request.getParameter("articleTitle");
        Map<String,Object> map = new HashMap<>();
        map.put("authorId",userId);
        map.put("category",category);
        map.put("articleTitle",articleTitle);
        if (monthTime == ""){
            if (yearTime == ""){//年月都为空
                map.put("time","");
                map.put("queryTime","");
            }else {
                //月为空
                map.put("time","year");
                map.put("queryTime",yearTime);
            }
        }else {
            //年月都存在
            map.put("time","month");
            map.put("queryTime",yearTime+monthTime);
        }

        List<Map<String,Object>> maps = articleService.queryArticleIndex(map);
        return AjaxResult.success(maps);
    }

    /**
     * 查询个人历史观看记录
     * @param
     * @return
     */
    @GetMapping("index/queryArticleHistory")
    @ResponseBody
    public AjaxResult queryArticleHistory() throws ParseException {
        List<Map<String, Object>> historyList = articleService.queryArticleHistory();


        //操作list，将list分为今天的list集合、昨天的list集合、以及更早的list集合
        List<Map<String, Object>> todayList = new ArrayList<>();
        List<Map<String, Object>> yesterdayList = new ArrayList<>();
        List<Map<String, Object>> earlyList = new ArrayList<>();

        for (int i = 0; i < historyList.size(); i++) {
            Map<String, Object> map = historyList.get(i);
            //浏览时间
            LocalDateTime lookTime = (LocalDateTime) map.get("createTime");
            Date createTime = Date.from(lookTime.atZone( ZoneId.systemDefault()).toInstant());
            //获取昨天晚上23点59分59秒的时间
            Date yesterdayTime = DateFormatUtil.getYesterdayDate(-1);
            //获取前天晚上23点59分59秒的时间
            Date qianDayTime = DateFormatUtil.getYesterdayDate(-2);
            if (yesterdayTime.before(createTime)){
                todayList.add(map);
            }
            if (qianDayTime.before(createTime) && yesterdayTime.after(createTime)){
                yesterdayList.add(map);
            }
            if (qianDayTime.after(createTime)){
                earlyList.add(map);
            }
        }

        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("todayList",todayList);
        resultMap.put("yesterdayList",yesterdayList);
        resultMap.put("earlyList",earlyList);

        return AjaxResult.success(resultMap);
    }

    /**
     * 前端获取文章数据(草稿箱编辑)
     * @param
     * @return
     */
    @GetMapping("/getArticleData")
    @ResponseBody
    public AjaxResult getArticleData(HttpServletRequest request){
        String articleId = request.getParameter("articleId");
        SysArticle byId = articleService.getById(articleId);
        return AjaxResult.success(byId);
    }

    @GetMapping("/index/queryArticleByTitle")
    @ResponseBody
    public AjaxResult queryArticleByTitle(String selectInput){
        QueryWrapper<SysArticle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("active",1)
                .eq("issued",1)
                .like("title",selectInput);
//        Page<Object> objectPage = new Page<>(1, 20);
        List<Map<String, Object>> mapList = articleService.queryAllArticleByTitle(selectInput);

        return AjaxResult.success(mapList);
    }



}
